/**
 * @author "Vlad Sumtsov"
 */
package com.corewillsoft.fireflies.gameobjects;

public class AreaObject {

	private float minX;
	private float maxX;
	private float minY;
	private float maxY;

	/**
	 * @param minX
	 *            left-top coordinate
	 * @param maxX
	 *            right-bottom coordinate
	 * @param minY
	 *            left-top coordinate
	 * @param maxY
	 *            right-bottom coordinate
	 */
	public AreaObject(float minX, float maxX, float minY, float maxY) {
		this.minX = minX;
		this.maxX = maxX;
		this.minY = minY;
		this.maxY = maxY;
	}

	/**
	 * @param gameObject
	 *            any gameObject
	 * @return true, if gameObject overlaps current area.
	 */
	public boolean isInArea(GameObject gameObject) {
		return isInArea(gameObject.getArea());
	}

	/**
	 * @param areaObject
	 *            any areaObject
	 * @return true, if in areaObject overlaps current areaObject.
	 */
	public boolean isInArea(AreaObject areaObject) {
		float areaObjMinX = areaObject.getMinX();
		float areaObjMaxX = areaObject.getMaxX();
		boolean isInX = isXInArea(areaObjMinX) || isXInArea(areaObjMaxX);

		float gameObjMinY = areaObject.getMinY();
		float gameObjMaxY = areaObject.getMaxY();
		boolean isInY = isYInArea(gameObjMinY) || isYInArea(gameObjMaxY);

		return isInY && isInX;
	}

	public boolean isXInArea(float x) {
		return (x < getMaxX()) && (x > getMinX());
	}

	public boolean isYInArea(float y) {
		return (y < getMaxY()) && (y > getMinY());
	}

	/**
	 * @param minX
	 *            new position for object. minX coordinate of top left corner
	 * @param minY
	 *            new position for object. minY coordinate of top left corner
	 *            Updates Max coordinates too.
	 */
	public void updatePosition(float minX, float minY) {
		this.maxX = minX + getWidth();
		this.maxY = minY + getHeight();

		this.minX = minX;
		this.minY = minY;
	}

	/**
	 * @return top left X coordinate.
	 *         Can be changed with {@link this.updatePosition} method
	 */
	public float getMinX() {
		return minX;
	}

	/**
	 * @return top left Y coordinate.
	 *         Can be changed with {@link this.updatePosition} method
	 */
	public float getMinY() {
		return minY;
	}

	/**
	 * @param maxX
	 *            - bottom left X coordinate
	 */
	public void setMaxX(float maxX) {
		this.maxX = maxX;
	}

	/**
	 * @return maxX
	 *         - bottom left X coordinate
	 */
	public float getMaxX() {
		return maxX;
	}

	public void setMaxY(float maxY) {
		this.maxY = maxY;

	}

	public float getMaxY() {
		return maxY;
	}

	// width and height
	public void setWidth(float width) {
		maxX = minX + width;
	}

	public float getWidth() {
		return maxX - minX;
	}

	public void setHeight(float height) {
		maxY = minY + height;
	}

	public float getHeight() {
		return maxY - minY;
	}

	/**
	 * checking on collision with left edge of rectangular wall
	 * @param gameObject
	 * @return
	 */
	public boolean isGameObjectNearLeftEdge(GameObject gameObject) {
		AreaObject gameObjectArea = gameObject.getArea();

		float minX = gameObject.getX();
		float minY = gameObject.getY();
		float maxX = gameObject.getX() + gameObjectArea.getWidth();
		float maxY = gameObject.getY() + gameObjectArea.getHeight();

		float leftEdgeX = getMinX();
		float bottomEdgeY = getMaxY();
		float upperEdgeY = getMinY();

		return ((maxX >= leftEdgeX) && (minX <= leftEdgeX)
				&& (maxY >= upperEdgeY) && (minY <= bottomEdgeY));
	}

	/**
	 * checking on collision with right edge of rectangular wall
	 * @param gameObject
	 * @return
	 */
	public boolean isGameObjectNearRightEdge(GameObject gameObject) {
		AreaObject gameObjectArea = gameObject.getArea();

		float minX = gameObject.getX();
		float minY = gameObject.getY();
		float maxX = gameObject.getX() + gameObjectArea.getWidth();
		float maxY = gameObject.getY() + gameObjectArea.getHeight();

		float rightEdgeX = getMaxX();
		float bottomEdgeY = getMaxY();
		float upperEdgeY = getMinY();

		return ((maxX >= rightEdgeX) && (minX <= rightEdgeX)
				&& (maxY >= upperEdgeY) && (minY <= bottomEdgeY));
	}

	/**
	 * checking on collision with upper edge of rectangular wall
	 * @param gameObject
	 * @return
	 */
	public boolean isGameObjectNearUpperEdge(GameObject gameObject) {
		AreaObject gameObjectArea = gameObject.getArea();

		float minX = gameObject.getX();
		float minY = gameObject.getY();
		float maxX = gameObject.getX() + gameObjectArea.getWidth();
		float maxY = gameObject.getY() + gameObjectArea.getHeight();

		float leftEdgeX = getMinX();
		float rightEdgeX = getMaxX();
		float upperEdgeY = getMinY();

		return ((maxY >= upperEdgeY) && (minY <= upperEdgeY)
				&& (maxX >= leftEdgeX) && (minX <= rightEdgeX));
	}

	/**
	 * checking on collision with bottom edge of rectangular wall
	 * @param gameObject
	 * @return
	 */
	public boolean isGameObjectNearBottomEdge(GameObject gameObject) {
		AreaObject gameObjectArea = gameObject.getArea();

		float minX = gameObject.getX();
		float minY = gameObject.getY();
		float maxX = gameObject.getX() + gameObjectArea.getWidth();
		float maxY = gameObject.getY() + gameObjectArea.getHeight();

		float leftEdgeX = getMinX();
		float rightEdgeX = getMaxX();
		float bottomEdgeY = getMaxY();

		return ((maxY >= bottomEdgeY) && (minY <= bottomEdgeY)
				&& (maxX >= leftEdgeX) && (minX <= rightEdgeX));
	}

}
